package com.twu.biblioteca;

import com.twu.biblioteca.model.Book;
import com.twu.biblioteca.model.Library;
import com.twu.biblioteca.model.Movie;
import com.twu.biblioteca.model.User;
import com.twu.biblioteca.util.CommandOption;
import com.twu.biblioteca.view.Reader;
import com.twu.biblioteca.view.UI;
import com.twu.biblioteca.view.Writer;

import java.util.Arrays;
import java.util.Collection;
import java.util.Optional;

public class BibliotecaApp {
    private final UI ui;
    private final Library<Book> bookLibrary;
    private final Library<Movie> movieLibrary;
    private final UserManager userManager;
    private boolean running;
    private Optional<User> currentUser;


    public BibliotecaApp(UI ui, Library<Book> bookLibrary, Library<Movie> movieLibrary, UserManager userManager){
        this.ui = ui;
        this.bookLibrary = bookLibrary;
        this.movieLibrary = movieLibrary;
        this.userManager = userManager;
        currentUser =  Optional.empty();
        running=false;
    }


    public static void main(String[] args) {
        UI ui = new UI(new Writer(System.out), new Reader(System.in));
        Library<Book> bookLibrary = new Library<>();
        Library<Movie> movieLibrary = new Library<>();
        UserManager userManager = new UserManager();
        BibliotecaApp app = new BibliotecaApp(ui, bookLibrary, movieLibrary, userManager);
        fillWithDummyData(bookLibrary, movieLibrary, userManager);
        app.start();
    }

    private static void fillWithDummyData(Library<Book> bookLibrary, Library<Movie> movieLibrary, UserManager userManager) {
        Book book = new Book("Fancy Title", "Fancy Author", 2014);
        bookLibrary.addItem(book);

        Movie movie = new Movie("Fancy Movie", 2014, "Fancy Director", Optional.of(10));
        movieLibrary.addItem(movie);

        User user = new User("Stefanie Grewenig", "sgreweni@thoughtworks.com", "+49 (0) 171 5213981", "123-4567", "pw");
        userManager.addUser(user);
    }


    public void start() {
        ui.showWelcomeMessage();
        ui.showOptions(CommandOption.getValues(false));
        running=true;

        while(running){
            Optional<CommandOption> result = CommandOption.getFromKey(ui.commandEntered(), currentUser.isPresent());
            if(result.isPresent()){
                result.get().getCommand().execute(this);
            } else {
                ui.showInvalidMenuOption();
            }

        }
    }

    public void listAvailableBooks(){
        ui.showBooks(bookLibrary.allAvailableItems());
    }

    public void listAvailableMovies(){
        ui.showMovies(movieLibrary.allAvailableItems());
    }

    public void checkOutBook() {
        ui.showCheckOutBookMessage();

        Optional<Book> result = bookLibrary.findItemByTitle(ui.commandEntered());

        if(result.isPresent()){
            bookLibrary.checkoutItem(result.get());
            ui.showCheckoutBookSuccessMessage();
        } else {
            ui.showCheckoutBookFailedMessage();
        }
    }

    public void returnBook() {
        ui.showReturnBookMessage();

        Optional<Book> result = bookLibrary.findItemByTitle(ui.commandEntered());

        if(result.isPresent()){
            bookLibrary.returnItem(result.get());
            ui.showReturnBookSuccessMessage();
        } else {
            ui.showReturnBookFailedMessage();
        }
    }

    public void checkOutMovie() {
        ui.showCheckOutMovieMessage();

        Optional<Movie> result = movieLibrary.findItemByTitle(ui.commandEntered());

        if(result.isPresent()){
            movieLibrary.checkoutItem(result.get());
            ui.showCheckoutMovieSuccessMessage();
        } else {
            ui.showCheckoutMovieFailedMessage();
        }
    }

    public void returnMovie() {
        ui.showReturnMovieMessage();

        Optional<Movie> result = movieLibrary.findItemByTitle(ui.commandEntered());

        if(result.isPresent()){
            movieLibrary.returnItem(result.get());
            ui.showReturnMovieSuccessMessage();
        } else {
            ui.showReturnMovieFailedMessage();
        }
    }

    public void quit() {
        running=false;
    }

    public void login() {
        ui.showLoginLibraryNumberMessage();
        String libraryNumber = ui.commandEntered();

        ui.showLoginPasswordMessage();
        String password = ui.commandEntered();

        Optional<User> user = userManager.authenticateUser(libraryNumber, password);

        if(user.isPresent()){
            currentUser=user;
            ui.showOptions(CommandOption.getValues(currentUser.isPresent()));

        } else {
            ui.showLoginFailedMessage();
        }

    }

    public void logout() {
        currentUser = Optional.empty();
        ui.showOptions(CommandOption.getValues(currentUser.isPresent()));
    }

    public void showInfo() {
        ui.showUserInformation(currentUser.get());
    }
}
